package cn.stormbirds.stpaylib;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.widget.Toast;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import cn.stormbirds.stpaylib.handler.UnionPayHandler;
import cn.stormbirds.stpaylib.handler.WxPayHandler;
import okhttp3.FormBody;
import okhttp3.Request;
import okhttp3.Response;

import static cn.stormbirds.stpaylib.STPaySDK.appTransUrl;
import static cn.stormbirds.stpaylib.STPaySDK.mOkHttpClient;
import static cn.stormbirds.stpaylib.bean.STPayCodes.CHANNEL_UNIONPAY;
import static cn.stormbirds.stpaylib.bean.STPayCodes.CODE_ERROR_CLIENT;
import static cn.stormbirds.stpaylib.bean.STPayCodes.CODE_ERROR_FAIL;
import static cn.stormbirds.stpaylib.bean.STPayCodes.CODE_ERROR_PERMISSION_DENIED;
import static cn.stormbirds.stpaylib.bean.STPayCodes.CODE_FAIL_CANCEL;
import static cn.stormbirds.stpaylib.bean.STPayCodes.CODE_SUCCESS;
import static cn.stormbirds.stpaylib.bean.STPayCodes.TRANSACTION_APP;

/**
 * Copyright (c) 小宝 @2019
 *
 * @ Package Name:    cn.stormbirds.stpaylib
 * @author         stormbirds
 * @ Email：          xbaojun@gmail.com
 * @ Created At：     2019/6/25 16:11
 * @ Description：
 */


public class PaymentActivity extends Activity implements Handler.Callback {
    public static final String EXTRA = "preOrder";
    /**
     * 银联权限申请结果回调码
     */
    private static final int STPAY_PERMISSIONS_REQUEST_FOR_UNION = 101;
    private boolean mClose = false;
    private JSONObject preOrder;
    private Handler mHandler = null;

    public PaymentActivity() {
    }

    @Override
    protected void onCreate(Bundle paramBundle) {
        super.onCreate(paramBundle);
        mHandler = new Handler(this);
        preOrder = JSON.parseObject(getIntent().getStringExtra(EXTRA)) ;
        if (STPaySDK.mBasePayHandler instanceof WxPayHandler) {
            ((WxPayHandler)STPaySDK.mBasePayHandler).onCreate(this);
        }else if(STPaySDK.mBasePayHandler instanceof UnionPayHandler){
            ((UnionPayHandler)STPaySDK.mBasePayHandler).onCreate(this);
            // 检查银联权限
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                PayLog.d("检查银联支付所需权限...");
                try {
                    if (ContextCompat.checkSelfPermission(this,
                            Manifest.permission.READ_PHONE_STATE)
                            != PackageManager.PERMISSION_GRANTED) {
                        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                                Manifest.permission.READ_PHONE_STATE)) {
                            Toast.makeText(this, "使用银联支付，请接受以下权限", Toast.LENGTH_SHORT).show();
                        }
                        ActivityCompat.requestPermissions(this,
                                new String[]{Manifest.permission.READ_PHONE_STATE},
                                STPAY_PERMISSIONS_REQUEST_FOR_UNION);
                        return;
                    }
                } catch (NoClassDefFoundError e) {
                    e.printStackTrace();
                    STPaySDK.mBasePayHandler.onPayFinished(PayResult.makeResult(CODE_ERROR_CLIENT,CHANNEL_UNIONPAY,TRANSACTION_APP,"请使用最新的 Android v4 Support Library，Android 6.0 以上需要申请权限") );
                    return;
                }
            }
            doUnionPay();
        }



    }

    private void doUnionPay(){

        STPaySDK.threadPoolUtils(new Runnable() {
            @Override
            public void run() {
                FormBody.Builder builder = new FormBody.Builder();
                for (String key : preOrder.keySet()) {
                    //追加表单信息
                    builder.add(key, String.valueOf(preOrder.getString(key)) );
                }
                Request requestTN = new Request.Builder().post(builder.build()).url(String.format(appTransUrl,STPaySDK.isTest?".test":"")).build();

                Response responseTN = null;
                try {
                    responseTN = mOkHttpClient.newCall(requestTN).execute();
                    final String tn = formatUrlResult(responseTN.body().string()).get("tn") ;
                    /*****************************************************************
                     * mMode参数解释： "00" - 启动银联正式环境 "01" - 连接银联测试环境
                     *****************************************************************/
//                    UPPayAssistEx.startPay(activity, null, null, tn, STPaySDK.isTest?"01":"00");
                    final String mode = STPaySDK.isTest?"01":"00";
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("tn",tn);
                    jsonObject.put("mode",mode);

                    Message msg = mHandler.obtainMessage();
                    msg.obj = jsonObject;
                    mHandler.sendMessage(msg);

                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case STPAY_PERMISSIONS_REQUEST_FOR_UNION: {
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    doUnionPay();

                } else {
                    STPaySDK.mBasePayHandler.onPayFinished(PayResult.makeResult(CODE_ERROR_PERMISSION_DENIED,CHANNEL_UNIONPAY,TRANSACTION_APP,"银联渠道所需权限被用户拒绝") );
                }
                break;
            }
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if (STPaySDK.mBasePayHandler instanceof WxPayHandler) {
            ((WxPayHandler)STPaySDK.mBasePayHandler).onNewIntent(this, intent);
        }else if(STPaySDK.mBasePayHandler instanceof UnionPayHandler){
            ((UnionPayHandler)STPaySDK.mBasePayHandler).onNewIntent(this, intent);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (this.mClose) {
            this.finish();
        }

        this.mClose = true;
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    public void onDestroy() {
        if (STPaySDK.mBasePayHandler instanceof WxPayHandler) {
            ((WxPayHandler)STPaySDK.mBasePayHandler).onDestroy();
        }else if(STPaySDK.mBasePayHandler instanceof UnionPayHandler){
            ((UnionPayHandler)STPaySDK.mBasePayHandler).onDestroy();
        }
        STPaySDK.mBasePayHandler = null;
        super.onDestroy();
    }

    @Override
    public void onBackPressed() {
        if (STPaySDK.mBasePayHandler != null) {
            STPaySDK.mBasePayHandler.onPayFinished(PayResult.makeResult(4004, 1));
        }

        super.onBackPressed();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (data == null) {
            return;
        }

        /*
         * 支付控件返回字符串:success、fail、cancel 分别代表支付成功，支付失败，支付取消
         */
        String str = data.getExtras().getString("pay_result");
        if (str.equalsIgnoreCase("success")) {

            // 如果想对结果数据验签，可使用下面这段代码，但建议不验签，直接去商户后台查询交易结果
            // result_data结构见c）result_data参数说明
//            if (data.hasExtra("result_data")) {
//                String result = data.getExtras().getString("result_data");
//                try {
//                    JSONObject resultJson = JSON.parseObject(result);
//                    String sign = resultJson.getString("sign");
//                    String dataOrg = resultJson.getString("data");
//                    // 此处的verify建议送去商户后台做验签
//                    // 如要放在手机端验，则代码必须支持更新证书
//                    boolean ret = true /*verify(dataOrg, sign, mMode)*/;
//                    if (ret) {
//                        // 验签成功，显示支付结果
//                        msg = "支付成功！";
//                    } else {
//                        // 验签失败
//                        msg = "支付失败！";
//                    }
//                } catch (JSONException e) {
//                }
//            }
            // 结果result_data为成功时，去商户后台查询一下再展示成功
//            msg = "支付成功！";
            STPaySDK.mBasePayHandler.onPayFinished(PayResult.makeResult(CODE_SUCCESS, CHANNEL_UNIONPAY,1,data.getExtras().getString("result_data")));
        } else if (str.equalsIgnoreCase("fail")) {
            // 支付失败！
            STPaySDK.mBasePayHandler.onPayFinished(PayResult.makeResult(CODE_ERROR_FAIL, CHANNEL_UNIONPAY));
        } else if (str.equalsIgnoreCase("cancel")) {
            //用户取消了支付"
            STPaySDK.mBasePayHandler.onPayFinished(PayResult.makeResult(CODE_FAIL_CANCEL, CHANNEL_UNIONPAY));
        }
        STPaySDK.mBasePayHandler.onPayFinished(PayResult.makeResult(CODE_ERROR_FAIL, CHANNEL_UNIONPAY));
    }

    @Override
    public boolean handleMessage(Message msg) {
        if (msg.obj instanceof JSONObject){
            JSONObject jsonObject = (JSONObject) msg.obj;
            STPaySDK.mBasePayHandler.realPay(PaymentActivity.this,jsonObject);
        }
        return false;
    }

    /**
     * bizType=000000&txnSubType=01&orderId=efbd824538874b52a3ae9c596157fe95&txnType=01&
     * encoding=UTF-8&version=5.1.0&accessType=0&txnTime=20190704152817&respMsg=成功[0000000]&
     * merId=777290058152763&tn=509872649233272016301&signMethod=01&respCode=00
     * url拼接字符串转为Map
     * @param result
     * @return
     */
    private Map<String,String> formatUrlResult(String result){
        String[] parms = result.split("&");
        Map<String,String> map = new HashMap<>();
        for(String parm:parms){
            String key = parm.substring(0,parm.indexOf("="));
            String value = parm.substring(parm.indexOf("=")+1);
            map.put(key,value);
        }
        return map;
    }
}
